package dryven.view.engine.expression.nodetypes;

import java.util.HashMap;
import java.util.Map;

import dryven.codegen.asm.MethodBuilder;
import dryven.codegen.asm.TempValue;
import dryven.reflection.TypeRef;
import dryven.view.engine.expression.ExpressionNode;
import dryven.view.engine.expression.nodelisters.NodeLister;

public abstract class AbstractExpressionNode implements ExpressionNode {

	private Map<String, ExpressionNode> _childNodes;
	private NodeLister _lister;
	private boolean _listerRun = false;
	
	public AbstractExpressionNode(NodeLister lister) {
		_lister = lister;
	}
	
	@Override
	public ExpressionNode getChildByName(String name) {
		runListerIfNeccesary();
		ExpressionNode node = null;
		if(_childNodes!=null) {
			node = _childNodes.get(name);
		}
		if(node==null && allowsWildChar()) {
			node = _lister.createWildCharNode(name);
		}
		return node;
	}

	@Override
	public Iterable<ExpressionNode> getChildren() {
		runListerIfNeccesary();
		if(_childNodes==null) {
			return null;
		}
		return _childNodes.values();
	}

	protected void addChildNode(ExpressionNode node) {
		if(_childNodes==null) {
			_childNodes = new HashMap<String, ExpressionNode>();
		}
		_childNodes.put(node.getName(), node);
	}
	
	@Override
	public boolean hasChildren() {
		runListerIfNeccesary();
		return _childNodes!=null && _childNodes.size()!=0;
	}

	@Override
	public boolean allowsWildChar() {
		return _lister.allowsWildChar();
	}
	
	private void runListerIfNeccesary() {
		if(!_listerRun) {
			if(_lister!=null) {
				for (ExpressionNode node : _lister.getChildNodes()) {
					addChildNode(node);
				}
			}
			_listerRun = true;
		}
	}
}
